/**
 * Copyright (C), 2019-2023,
 * FileName: ContactsSerivce
 * Author:   fanxquer
 * Date:     2023/7/6 16:06
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 邱富康           2023/7/6           1.0
 */
package com.hsteach.service.contact;

import com.google.common.collect.Lists;
import com.hsteach.common.core.domain.model.AuthInfo;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.StringUtils;
import com.hsteach.framework.feign.IdentityEnum;
import com.hsteach.framework.feign.client.uapi.vo.*;
import com.hsteach.framework.feign.client.xgk.dto.GetTeacherInfoEntity;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetParentsRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetTeacherRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.ParentEntity;
import com.hsteach.framework.feign.client.xgk.dto.ret.preschool.PreschoolGetParentsRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.preschool.PreschoolGetTeacherRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.preschool.PreschoolParentEntity;
import com.hsteach.framework.web.service.UApiService;
import com.hsteach.service.third.PreschoolXgkService;
import com.hsteach.service.third.XgkService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 〈通讯录〉
 *
 * @author Qiu Fukang
 * @create 2023/7/6
 * @since 1.0.0
 */
@Service
public class ContactsService {

    @Resource
    private XgkService xgkService;
    @Resource
    private UApiService uApiService;
    @Resource
    private PreschoolXgkService preschoolXgkService;

    public List<GetTeacherRet> getTeachers(String searchWord) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<GetTeacherRet> ret;
        if (IdentityEnum.PARENT.getCode().equals(authInfo.getIdentity())) {
            GetTeacherInfoEntity entity = new GetTeacherInfoEntity();
            entity.setClassId(authInfo.getCurrentStudent().getEclassId());
            ret = xgkService.getTeachersByClassId(authInfo.getCurrentStudent().getEclassId());
        } else {
            ret = xgkService.getTeachers(authInfo.getId());
        }
        if (StringUtils.isNotEmpty(searchWord)) {
            ret = ret.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord) || Optional.ofNullable(e.getPhone()).orElse("").contains(searchWord)).collect(Collectors.toList());
        }
        ret.forEach(it -> it.setIdcardNo(""));
        return ret;
    }

    public List<GetParentsRet> getParent(String searchWord) {
        List<GetParentsRet> parent = xgkService.getParent(SecurityUtils.getAuthInfo().getId());
        parent = parent.stream().peek(e -> {
            HashSet<String> parentIds = new HashSet<>();
            ArrayList<ParentEntity> result = new ArrayList<>();
            e.getParents().forEach(it->{
                if (!parentIds.contains(it.getPersonId()+"_"+it.getChildId())){
                    result.add(it);
                    parentIds.add(it.getPersonId()+"_"+it.getChildId());
                }
            });
            e.setParents(result);
        }).filter(e -> e.getParents().size() != 0).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(searchWord)) {
            parent = parent.stream().peek(e -> {
                List<ParentEntity> collect = e.getParents().stream().filter(k ->
                                Optional.ofNullable(k.getChildName()).orElse("").contains(searchWord) || Optional.ofNullable(k.getPhone()).orElse("").contains(searchWord))
                        .collect(Collectors.toList());
                e.setParents(collect);
            }).filter(e -> e.getParents().size() != 0).collect(Collectors.toList());
        }

        return parent;
    }

    public LinkedHashMap<String, List<DepartTeacher>> getDepartTeachers(String searchWord) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<DepartTeacher> allDepartTeacher = uApiService.getAllDepartTeacher(authInfo.getAccessToken(), authInfo.getAppToken());
        if (StringUtils.isNotEmpty(searchWord)) {
            allDepartTeacher = allDepartTeacher.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord) || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)).collect(Collectors.toList());
        }

        LinkedHashMap<String, List<DepartTeacher>> result = new LinkedHashMap<>();
        allDepartTeacher.stream().filter(it->!it.getOrganizeName().equals("测试部门")).forEach(e -> {
            e.setIcNumber("");
            if (result.containsKey(e.getOrganizeName())) {
                result.get(e.getOrganizeName()).add(e);
            } else {
                List<DepartTeacher> list = Lists.newArrayList();
                list.add(e);
                result.put(e.getOrganizeName(), list);
            }
        });
        return result;
    }

    public Map<String, List<Leader>> getLeaders(String searchWord, String xxlType) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();

        Map<String, List<Leader>> ret = new HashMap<>();
        if (StringUtils.isNotEmpty(xxlType)) {
            Stream.of(xxlType.split(",")).forEach(it -> {
                List<Leader> allLeader = uApiService.getAllLeader(authInfo.getAccessToken(), authInfo.getAppToken(), xxlType, null);
                allLeader = allLeader.stream().filter(e -> StringUtils.isNotEmpty(e.getSchoolName())).collect(Collectors.toList());
                if (StringUtils.isNotEmpty(searchWord)) {
                    allLeader = allLeader.stream().filter(e ->
                            Optional.ofNullable(e.getName()).orElse("").contains(searchWord)
                                    || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)
                                    || Optional.ofNullable(e.getSchoolName()).orElse("").contains(searchWord)).collect(Collectors.toList());
                }
                allLeader.forEach(item -> item.setIcNumber(""));
                Map<String, List<Leader>> temp = allLeader.stream().collect(Collectors.groupingBy(Leader::getSchoolName));
                ret.putAll(temp);
            });
        }

        return ret;
    }

    /**
     * 幼教获取老师通讯录
     *
     * @param searchWord
     * @return
     */
    public List<PreschoolGetTeacherRet> getPreschoolTeachers(String searchWord) {
        List<PreschoolGetTeacherRet> ret = xgkService.getPreschoolTeachers(SecurityUtils.getAuthInfo().getId());
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(searchWord)) {
            ret = ret.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord) || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)).collect(Collectors.toList());
        }
        ret.forEach(it -> it.setIcNumber(""));
        return ret;
    }

    /**
     * 幼教获取家长通讯录
     *
     * @param searchWord
     * @return
     */
    public List<PreschoolGetParentsRet> getParentList(String searchWord) {
        List<PreschoolGetParentsRet> parent = xgkService.getParentList(SecurityUtils.getAuthInfo().getId());
        if (StringUtils.isNotEmpty(searchWord)) {
            parent = parent.stream().map(e -> {
                List<PreschoolParentEntity> parents = e.getParents();
                if (parents == null) {
                    return e;
                }
                List<PreschoolParentEntity> collect = parents.stream().filter(k ->
                        Optional.ofNullable(k.getStudentName()).orElse("").contains(searchWord) || Optional.ofNullable(k.getParentMobile()).orElse("").contains(searchWord)).collect(Collectors.toList());
                e.setParents(collect);
                return e;
            }).filter(e -> e.getParents() != null && e.getParents().size() != 0).collect(Collectors.toList());
        }
        return parent;
    }

    /**
     * 获取单位通讯录
     *
     * @param searchWord
     * @return
     */
    public List<Company> getCompanyList(String searchWord, String organizeId, Integer type) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<Company> companyList = uApiService.getCompanyList(authInfo.getAccessToken(), authInfo.getAppToken(), searchWord, organizeId, type);
        companyList.forEach(it -> it.setIcNumber(""));
        return companyList.stream().filter(it->!it.getName().equals("测试部门") && !it.getOrganizeName().contains("测试部门")).collect(Collectors.toList());
    }

    /**
     * 获取单位通讯录
     *
     * @return
     */
    public List<CompanyAndDept> getCompanyAndDeptList() {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<CompanyAndDept> list = uApiService.getCompanyAndDeptList(authInfo.getAccessToken(), authInfo.getAppToken());
        return list.stream().filter(it->!it.getName().equals("测试部门")).collect(Collectors.toList());
    }


    public List<PreschoolGetTeacherRet> preschoolTeachers(String accessToken, String searchWord, String classId) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<PreschoolGetTeacherRet> ret;
        if (IdentityEnum.PARENT.getCode().equals(authInfo.getIdentity()) && !StringUtils.isEmpty(classId)) {
            ret = preschoolXgkService.getPreschoolTeacherByClassId(accessToken, classId);
        } else {
            ret = preschoolXgkService.getPreschoolTeacherByClassId(accessToken, null);
        }
        if (StringUtils.isNotEmpty(searchWord)) {
            ret = ret.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord) || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)).collect(Collectors.toList());
        }
        ret.forEach(it -> it.setIcNumber(""));
        return ret;
    }

    public List<SchoolListVO> listSchool() {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        return uApiService.getAllSchool(authInfo.getAccessToken(), authInfo.getAppToken());
    }

    public List<Leader> listV2Leader(String searchWord, String schoolId) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<Leader> allLeader = uApiService.getAllLeader(authInfo.getAccessToken(), authInfo.getAppToken(), null, schoolId);
        allLeader = allLeader.stream().filter(e -> StringUtils.isNotEmpty(e.getSchoolName())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(searchWord)) {
            allLeader = allLeader.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord)
                            || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)
                            || Optional.ofNullable(e.getSchoolName()).orElse("").contains(searchWord)).collect(Collectors.toList());
        }
        allLeader.forEach(it -> it.setIcNumber(""));
        return allLeader;
    }

    public LinkedHashMap<String, Map<String, List<Leader>>> listV3Leader(String searchWord) {
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        String accessToken=authInfo.getAccessToken();
        String appToken=authInfo.getAppToken();
        List<SchoolListVO> allSchool = uApiService.getAllSchool(accessToken, appToken);
        allSchool = allSchool.stream().filter(it -> !it.getName().contains("佳发")).collect(Collectors.toList());
        List<Leader> allLeader = uApiService.getAllLeader(accessToken, appToken, null, null);
        allLeader.forEach(it -> it.setIcNumber(""));

        allLeader = allLeader.stream().filter(e -> StringUtils.isNotEmpty(e.getSchoolName())).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(searchWord)) {
            allLeader = allLeader.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(searchWord)
                            || Optional.ofNullable(e.getMobile()).orElse("").contains(searchWord)
                            || Optional.ofNullable(e.getSchoolName()).orElse("").contains(searchWord)).collect(Collectors.toList());
            Set<String> schoolIdSet = allLeader.stream().map(it -> it.getSchoolName() + "").collect(Collectors.toSet());
            allSchool = allSchool.stream().filter(it -> schoolIdSet.contains(it.getName()) || it.getName().contains(searchWord)).collect(Collectors.toList());
        }
        Map<String, List<SchoolListVO>> schoolXxlbMap = allSchool.stream().collect(Collectors.groupingBy(it -> {
            if ("111".equals(it.getXxlb())) {
                return it.getXxlb() + "-" + it.getXxbb();
            } else {
                return it.getXxlb();
            }
        }));
        Map<String, List<Leader>> schoolLeaderMap = allLeader.stream().collect(Collectors.groupingBy(Leader::getSchoolName));
        LinkedHashMap<String, Map<String, List<Leader>>> result = new LinkedHashMap<>();
        new LinkedHashMap<String, String>() {{
            put("公办幼儿园", "111-1");
            put("民办幼儿园", "111-2");
            put("小学", "211");
            put("初中", "311");
            put("九年一贯制", "312");
            put("高（完）中/十二年一贯制", "341,345,342");
            put("中等职业学校", "361");
            put("特殊教育学校", "350");
        }}.forEach((k, v) -> {
            List<SchoolListVO> temp = new ArrayList<>();
            Stream.of(v.split(",")).forEach(xxlb -> {
                List<SchoolListVO> tempSchool = schoolXxlbMap.getOrDefault(xxlb, new ArrayList<>());
                temp.addAll(tempSchool);
            });
            Map<String, List<Leader>> collect = temp.stream().collect(Collectors.toMap(SchoolListVO::getName, it -> {
                List<Leader> leaderTemp = schoolLeaderMap.getOrDefault(it.getName(), new ArrayList<>());
                //按照getWorkRoleNames排序
                List<Leader> firstList = leaderTemp.stream().filter(item -> StringUtils.isNotEmpty(item.getWorkRoleNames()) && item.getWorkRoleNames().contains("书记") && !item.getWorkRoleNames().contains("副书记")).collect(Collectors.toList());
                leaderTemp.removeAll(firstList);
                firstList.addAll(leaderTemp);

                return firstList;
            }));
            result.put(k, collect);
        });
        return result;
    }
}
